package com.fingard.dsp.bank.directbank.gzelink01;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.bankInterface.ITransaction;
import com.fingard.dsp.bank.reqrespobj.transaction.Req7515TodayTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.Req7516HisTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.RetAtsTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.detail.RetAtsTransDetail;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;

import java.util.Calendar;
import java.util.Date;

/**
 * 广银联历史明细查询
 * <p>
 * 参考接口文档：代收付系统接口v2.5.doc
 *
 * @author Cruise
 * @date 2019/3/19
 */
public class GZELINK01Transaction extends GZELINK01Base implements ITransaction {
    @Override
    public RetAtsTrans d_7516_HisTrans(Req7516HisTrans p_req7516) throws Exception {
        RetAtsTrans retAts = new RetAtsTrans(p_req7516.reqHeader);
        retAts.writeStart();

        String tmpRespCode = "";
        String tmpRespInfo = "";

        try {
            Calendar tmpCalendarFrom = Calendar.getInstance();
            tmpCalendarFrom.setTime(p_req7516.getDateFrom());

            Calendar tmpCalendarTo = Calendar.getInstance();
            tmpCalendarTo.setTime(p_req7516.getDateTo());

            int tmpIntDateFrom = 0;
            int tmpIntDateTo = 0;
            while (tmpIntDateFrom <= tmpIntDateTo && tmpRespCode.length() == 0) {
                Calendar tmpClndrStepTo = Calendar.getInstance();
                tmpClndrStepTo.setTime(tmpCalendarFrom.getTime());
                if (DateHelper.compareMonth(tmpCalendarFrom, tmpCalendarTo) == -1) {
                    tmpClndrStepTo.set(Calendar.DAY_OF_MONTH, tmpClndrStepTo.getActualMaximum(Calendar.DAY_OF_MONTH));
                } else {
                    tmpClndrStepTo.setTime(tmpCalendarTo.getTime());
                }

                ActSetItem actItem = getBankConfig().getActSetItem(p_req7516.actNum, "");
                if (actItem == null) {
                    retAts.writeRespCode("-1");
                    retAts.writeRespInfo("未找到账号:[" + p_req7516.actNum + "]商户配置信息!");
                    retAts.writeEnd();
                    return retAts;
                }

                GZELINK01Header bankHeader = new GZELINK01Header();
                bankHeader.transCode = "500002";
                bankHeader.reqSeqNo = getQryTransID();

                StringBuilder p_reqMsg = new StringBuilder();
                write7516CommonHeader(p_reqMsg, actItem, bankHeader);

                p_reqMsg.append("<QUERY_TRANS>");
                p_reqMsg.append("<ACCOUNT_TYPE>0</ACCOUNT_TYPE>");
                p_reqMsg.append("<MERCHANT_ID>" + actItem.merchantId + "</MERCHANT_ID>");
                p_reqMsg.append("<BEGIN_DATE>" + Format.Date8Format.format(tmpCalendarFrom.getTime()) + "</BEGIN_DATE>");
                p_reqMsg.append("<END_DATE>" + Format.Date8Format.format(tmpCalendarFrom.getTime()) + "</END_DATE>");
                p_reqMsg.append("<PAGE_NUM>1</PAGE_NUM>");
                p_reqMsg.append("<PAGE_SIZE>20</PAGE_SIZE>");
                p_reqMsg.append("<QUERY_REMARK></QUERY_REMARK>");
                p_reqMsg.append("</QUERY_TRANS>");
                p_reqMsg.append("</BODY>");
                p_reqMsg.append("</GZELINK>");

                String signData = p_reqMsg.toString().replaceAll("<SIGNED_MSG></SIGNED_MSG>", "");
                WriteBankLogLn2("广银联明细查询签名原始数据:\r\n" + signData);

                String signature = signMsg(signData, actItem);

                String reqData = p_reqMsg.toString().replaceAll("<SIGNED_MSG></SIGNED_MSG>", "<SIGNED_MSG>" + signature + "</SIGNED_MSG>");
                WriteBankLogStep2(reqData);

                String[] tmpStrRet = sendDataToGZE(reqData, bankFront.serverURL);
                WriteBankLogStep3(tmpStrRet[1]);

                if (tmpStrRet[0].length() != 0) {
                    tmpRespCode = "-1";
                    tmpRespInfo = tmpStrRet[1];
                    break;
                }

                int page = analysis7516Loop(tmpStrRet, p_req7516, retAts);
                for (int i = 2; i <= page; i++) {
                    bankHeader.reqSeqNo = getQryTransID();

                    StringBuilder tmpRequest = new StringBuilder();
                    write7516CommonHeader(tmpRequest, actItem, bankHeader);

                    tmpRequest.append("<QUERY_TRANS>");
                    tmpRequest.append("<ACCOUNT_TYPE>0</ACCOUNT_TYPE>");
                    tmpRequest.append("<MERCHANT_ID>" + actItem.merchantId + "</MERCHANT_ID>");
                    tmpRequest.append("<BEGIN_DATE>" + Format.Date8Format.format(tmpClndrStepTo.getTime()) + "</BEGIN_DATE>");
                    tmpRequest.append("<END_DATE>" + Format.Date8Format.format(tmpClndrStepTo.getTime()) + "</END_DATE>");
                    tmpRequest.append("<PAGE_NUM>" + i + "</PAGE_NUM>");
                    tmpRequest.append("<PAGE_SIZE>20</PAGE_SIZE>");
                    tmpRequest.append("<QUERY_REMARK></QUERY_REMARK>");
                    tmpRequest.append("</QUERY_TRANS>");
                    tmpRequest.append("</BODY>");
                    tmpRequest.append("</GZELINK>");

                    signData = tmpRequest.toString().replaceAll("<SIGNED_MSG></SIGNED_MSG>", "");
                    WriteBankLogLn2("广银联明细查询签名原始数据:\r\n" + signData);

                    signature = signMsg(signData, actItem);

                    reqData = tmpRequest.toString().replaceAll("<SIGNED_MSG></SIGNED_MSG>", "<SIGNED_MSG>" + signature + "</SIGNED_MSG>");
                    WriteBankLogStep2(reqData);

                    tmpStrRet = sendDataToGZE(reqData, bankFront.serverURL);
                    WriteBankLogStep3(tmpStrRet[1]);

                    analysis7516Loop(tmpStrRet, p_req7516, retAts);
                }

                tmpCalendarFrom = tmpClndrStepTo;
                tmpCalendarFrom.add(Calendar.DAY_OF_MONTH, 1);
                tmpIntDateFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
                tmpIntDateTo = Integer.parseInt(Format.Date8Format.format(tmpCalendarTo.getTime()));
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRespCode = "-1";
            tmpRespInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        if ("-1".equals(tmpRespCode)) {
            retAts.writeRespCode(tmpRespCode);
            retAts.writeRespInfo(tmpRespInfo);
        } else if (retAts.getWrittenRdCount() == 0) {
            retAts.writeRespCode("0");
            retAts.writeRespInfo("交易为空");
        }

        retAts.writeEnd();
        return retAts;
    }

    @Override
    public RetAtsTrans d_7515_TodayTrans(Req7515TodayTrans p_req7515) throws Exception {
        Req7516HisTrans tmpReq7516 = new Req7516HisTrans(p_req7515.reqHeader);

        tmpReq7516.actArea = p_req7515.actArea;
        tmpReq7516.actCur = p_req7515.actCur;
        tmpReq7516.actNum = p_req7515.actNum;

        String tmpStrToday = Format.Date8Format.format(new Date());
        tmpReq7516.dateFrom = tmpStrToday;
        tmpReq7516.dateTo = tmpStrToday;

        return d_7516_HisTrans(tmpReq7516);
    }

    public int analysis7516Loop(String[] tmpStrRet, Req7516HisTrans p_req7516, RetAtsTrans retAts) throws Exception {
        int page = -1;
        RetAtsTransDetail tmpRetDetail = new RetAtsTransDetail();
        if (tmpStrRet[0].length() == 0) {
            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
            if (tmpBkReader != null) {
                String totalPageNum = tmpBkReader.getFirstText("/GZELINK/BODY/QUERY_TRANS/PAGE_SUM");
                page = Integer.parseInt(totalPageNum);

                String bankRetCode = tmpBkReader.getFirstText("/GZELINK/INFO/RET_CODE");
                if ("0000".equals(bankRetCode)) {
                    while (tmpBkReader.read("/GZELINK/BODY/RET_DETAILS/RET_DETAIL")) {
                        XElement readXElement = tmpBkReader.readedXElement;
                        tmpRetDetail.cur = p_req7516.actCur;
                        tmpRetDetail.actArea = p_req7516.actArea;
                        tmpRetDetail.actNum = p_req7516.actNum;

                        String transTime = readXElement.getSingleTextNotNull("TRAN_TIME");
                        tmpRetDetail.tranDate = Format.Date10Format.format(Format.DateTime14Format.parse(transTime));
                        tmpRetDetail.valueDate = tmpRetDetail.tranDate;
                        tmpRetDetail.tranTime = Format.DateTimeFormat.format(Format.DateTime14Format.parse(transTime));
                        String tranAmt = readXElement.getSingleTextNotNull("TRAN_AMT");
                        tmpRetDetail.tranAmt = StringHelper.amountDivide100(tranAmt.replace("-", ""));
                        String accBal = readXElement.getSingleTextNotNull("BALANCE");
                        tmpRetDetail.accBal = StringHelper.amountDivide100(accBal);
                        String cdFlag = "";
                        if ("-".equals(tranAmt.substring(0, 1))) {
                            cdFlag = "1";
                        } else {
                            cdFlag = "2";
                        }
                        tmpRetDetail.cdFlag = cdFlag;
                        tmpRetDetail.usage = readXElement.getSingleTextNotNull("REMARK");
                        tmpRetDetail.abstr = readXElement.getSingleTextNotNull("REMARK");
                        tmpRetDetail.payCode = readXElement.getSingleTextNotNull("REMARK");
                        nodeAnalysic(readXElement, tmpRetDetail, getCharset());
                        retAts.writeRetDetailWithoutRespCode(tmpRetDetail);
                    }
                } else {
                    retAts.writeRespCode("-1");
                    retAts.writeRespInfo(tmpBkReader.getFirstText("/GZELINK/INFO/ERR_MSG"));
                }
            } else {
                retAts.writeRespCode("-1");
                retAts.writeRespInfo(tmpSbMsg.toString());
            }
        } else {
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(tmpStrRet[0].toString());
        }

        return page;
    }
}
